unit uFileLogger;

interface

uses
  Windows, SysUtils, uCriticalSection;

type

  TFileLogger = class
  protected
    m_FileLoggerLock: TCriticalSection;
    m_sPath: String;
    m_sFileName: String;
    
    m_sData: String;
    FLogFile: TextFile;
    m_bReWriteFile: Boolean;
    m_bShowProcessId: Boolean;
    m_bShowThreadId: Boolean;
    m_bShowDateTime: Boolean;
    m_bLog: Boolean;
  private
    procedure InitFileLog;
    function FormatMessage(const Msg: String): String;
  published
    property IsReWriteFile: Boolean read m_bReWriteFile write m_bReWriteFile;
    property IsShowProcessId: Boolean read m_bShowProcessId write m_bShowProcessId;
    property IsShowThreadId: Boolean read m_bShowThreadId write m_bShowThreadId;
    property IsShowDateTime: Boolean read m_bShowDateTime write m_bShowDateTime;
  public
    procedure WriteLogMsg(const sMsg: String);
  public
    constructor Create;
    destructor Destroy; override;
  end;

  var
    _FileLogger: TFileLogger;
  
implementation

constructor TFileLogger.Create;
begin
  inherited Create;
  m_bReWriteFile   := False;
  m_bShowProcessId := TRUE;
  m_bShowThreadId  := TRUE;
  m_bShowDateTime  := TRUE;
  m_bLog := FALSE;
  m_FileLoggerLock := TCriticalSection.Create;
  InitFileLog;
end;

procedure TFileLogger.InitFileLog;
begin
  m_sData := FormatDateTime('yyyymmdd', Now());
  m_sPath := ExtractFilePath(ParamStr(0))+'Log';
  if not  DirectoryExists(m_sPath) Then CreateDir(m_sPath);
  m_sFileName := ExtractFilePath(ParamStr(0))+'Log\'+m_sData+'.txt';

  try
    AssignFile(FLogFile, m_sFileName);
    if (FileExists(m_sFileName)) then
      append(FLogFile)
    else
      rewrite(FLogFile);
    Closefile(FLogFile);
    m_bLog := True;
  except
    m_bLog := False;
  end;
end;

destructor TFileLogger.Destroy;
begin
  FreeAndNil(m_FileLoggerLock);
  inherited Destroy;
end;

function TFileLogger.FormatMessage(const Msg: String): String;
var
  ProcessID: String;
  ThreadID: String;
begin
  if m_bShowDateTime then
    Result := FormatDateTime('hh:nn:ss',Now)+' ';
    
  if m_bShowProcessId then begin
    ProcessID := IntToStr(GetCurrentProcessID());
    Result := Result + 'ProcessID: '+ ProcessID+' ';
  end;

  if m_bShowThreadId then begin
    ThreadID := IntToStr(GetCurrentThreadID());
    Result := Result + 'ThreadID: '+ ThreadID+' ';
  end;

  Result := Result + Msg;
end;

procedure TFileLogger.WriteLogMsg(const sMsg: String);
begin
  try
    m_FileLoggerLock.Lock;
    Append(FLogFile);
    Writeln(FLogFile, FormatMessage(sMsg));
    flush(FLogFile);
    CloseFile(FLogFile);//
  finally
    m_FileLoggerLock.UnLock;
  end;
end;

initialization
  _FileLogger := TFileLogger.Create;

finalization
  _FileLogger.Free;
end.
